void 、 void* 和 NULL的理解

您所在的位置:网站首页 null>0会不会空指针 void 、 void* 和 NULL的理解

void 、 void* 和 NULL的理解

2024-07-17 11:10| 来源: 网络整理| 查看: 265

前言

一个指针变量可以指向计算机任何一块内存,不管该内存有没有被分配,也不管该内存有没有使用权限,只要把该内存地址给它,他就可以指向该内存,C语言没有一种机制来保证指针指向内存的正确性,所以程序员必须提高警惕。

需使用初始化的局部变量

先看一段代码

#include #include #pragma warning(disable:4996) int main() { char *arr; gets(arr); printf("%s\n", arr); system("pause"); return 0; }

这段程序本没有语法错误,但在vs2013会报错,即arr未初始化,但在有的编译器当中当输入字符串之后,按回车程序直接崩溃,而在Linux表现这段错误(Segment Fault),这是为什么?

未初始化的局部变量的值是不确定的,C语言没有做规定,不同编译器可能有不同结果(所以不要使用没初始化的局部变量),在上例子中arr就是未初始化的局部变量(指针变量也是变量),他的值是未知的,指向哪块内存也不知道,大多数情况这块内存没有被分配,或者没有读写权限。

所以,没有初始化的指针变量初始化为NULL

char *arr = NULL; NULL

NULL是“零值”的意思,表示空指针,从表面上理解空指针是不指向任何数据的指针,是无效指针,程序使用不会产生任何效果。(注意区分大小写,null没任何含义)

在上例子中会出现什么效果呢!

#include #include #pragma warning(disable:4996) int main() { char *arr = NULL; gets(arr); printf("%s\n", arr); system("pause"); return 0; } 运行之后发现还有错,(1)gets()不会让用户输入字符串,也不会向指针指向的内存写入数据;(2)printf()不会读取指针指向的内容,只是给出提示,让用户意识到使用了一个空指针;

实际上很多库函数都会对空指针进行判空:(防止对空指针进行无意义的操作)

(1) if(psrc == NULL) return 0; else {;} (2) //断言,头文件#include assert(psrc);//或者 assert(psrc!=NULL); //如果为空,他会报错到具体哪一行

请看下图:

看到其实NULL是一个宏,(void *)0表示把0强制转化为void*类型,最外层()防止发生优先级等问题。所以,NULL指向了地址为0的内存,不是不指向任何输入。

在大多数操作系统中,极小的地址通常不保存数据,也不允许程序访问,NULL可以指向这段地址区间的任何一个地址。

注:(1)C语言并没有规定NULL的指向,只是大部分标准库规定将NULL指向0;

       (2)NULL和NUL的区别,NULL表示一个宏定义,空指针,可在代码中使用,NUL表示字符串结束标志'\0',NUL没有在C语言中定义,所以不可以在代码中使用。

void*

void不可以定义变量,因为定义变量前提是要开辟空间,而void是空类型。void*可以定义变量,指针在32位平台占4个byte,但是void*定义的变量不可以解引用。

void用在函数定义当中可以表示函数没有返回值,或者没有形式参数,,而void*表示指针指向的数据的类型是未知的。void*表示一个有效的指针,他确实指向一个实实在在的数据,可是数据的类型尚未确定,在后续的使用过程一般要强制类型转化。

例:

动态内存分配函数malloc(),原型定义如下:

void *malloc( size_t size );

malloc()的返回值为void*类型,所以在使用的时候要强制类型转化为需要的类型,请看下例

#include #include #pragma warning(disable:4996) int main() { char *arr = (char *)malloc(sizeof(char)*20);//开辟可以保存20个字符的内存大小,返回值转化为char* gets(arr); printf("%s\n", arr); system("pause"); return 0; }


【本文地址】


今日新闻


推荐新闻


    CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3